package com.zf.nio.buffer;

import java.nio.ByteBuffer;

/**
 * @author Zhou Feng
 */
public class ByteBufferDemo01 {
    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        // 将写模式 转为 读模式 ， 从缓冲区读取数据
        // 设置 limit = position; position=0 ，以便读取刚刚写入的数据
        // 该方法应该在 buffer 中被写入数据后，调用；
        // 如果在写入数据前调用，将导致buffer无法被写入数据，报错 BufferOverflowException
        buffer.flip();
        buffer.put((byte)12);

        // position=0, limit=capacity
        buffer.clear();

        // compact()方法将所有未读的数据拷贝到 Buffer 起始处。然后将 position 设到最后一
        //个未读元素正后面。limit 属性依然像 clear()方法一样，设置成 capacity。现
        buffer.compact();

        //mark()与 reset()方法
        //通过调用 Buffer.mark()方法，可以标记 Buffer 中的一个特定 position。之后可以通
        //过调用 Buffer.reset()方法恢复到这个 position。例如
        //buffer.mark();
        //buffer.get();
        //buffer.reset();


        //根据现有的缓冲区对象
        //来创建一个子缓冲区，即在现有缓冲区上切出一片来作为一个新的缓冲区，但现有的
        //缓冲区与创建的子缓冲区在底层数组层面上是数据共享的，也就是说，子缓冲区相当
        //于是现有缓冲区的一个视图窗口。调用 slice()方法可以创建一个子缓冲区。
        ByteBuffer bf2 = ByteBuffer.allocate(20);
        // 创建子缓冲区
        bf2.position(3);
        bf2.limit(7);
        ByteBuffer slice = bf2.slice();

        //只读缓冲区
        //只读缓冲区非常简单，可以读取它们，但是不能向它们写入数据。可以通过调用缓冲
        //区的 asReadOnlyBuffer()方法，将任何常规缓冲区转 换为只读缓冲区，这个方法返回
        //一个与原缓冲区完全相同的缓冲区，并与原缓冲区共享数据，只不过它是只读的。如
        //果原缓冲区的内容发生了变化，只读缓冲区的内容也随之发生变化
        // 创建只读缓冲区
        ByteBuffer readonly = buffer.asReadOnlyBuffer();

        // 直接缓冲区， 不在JVM堆中
        //它会在每一次调用底层操作系统 I/O 操作之前(或之后)，
        //尝试避免将缓冲区的内容拷贝到一个中间缓冲区中 或者从一个中间缓冲区中拷贝数据。
        ByteBuffer allocateDirect = ByteBuffer.allocateDirect(20);

    }
}
